home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / info-service / gopher / Unix / gopher+1.2b4 / object / BLblock.c next >
Encoding:
C/C++ Source or Header  |  1993-03-26  |  7.7 KB  |  411 lines

  1. /********************************************************************
  2.  * lindner
  3.  * 3.2
  4.  * 1993/03/26 19:49:34
  5.  * /home/mudhoney/GopherSrc/CVS/gopher+/object/BLblock.c,v
  6.  * Exp
  7.  *
  8.  * Paul Lindner, University of Minnesota CIS.
  9.  *
  10.  * Copyright 1991, 1992, 1993 by the Regents of the University of Minnesota
  11.  * see the file "Copyright" in the distribution for conditions of use.
  12.  *********************************************************************
  13.  * MODULE: BLblock.c
  14.  * Implementation of Block handling routines.
  15.  *********************************************************************
  16.  * Revision History:
  17.  * BLblock.c,v
  18.  * Revision 3.2  1993/03/26  19:49:34  lindner
  19.  * More comments, memory leak fix, etc
  20.  *
  21.  * Revision 3.1.1.1  1993/02/11  18:03:06  lindner
  22.  * Gopher+1.2beta release
  23.  *
  24.  * Revision 2.1  1993/02/09  22:45:54  lindner
  25.  * Fixes for retrieving from the net.  New BLAsearch
  26.  *
  27.  * Revision 1.1  1993/01/31  00:22:51  lindner
  28.  * Initial revision
  29.  *
  30.  *
  31.  *********************************************************************/
  32.  
  33. #include "BLblock.h"
  34. #include "Malloc.h"
  35. #include <stdio.h>
  36. #include "String.h"
  37.  
  38. extern boolean DEBUG;
  39.  
  40. /*
  41.  * Make a new Block Object
  42.  */
  43.  
  44. Blockobj *
  45. BLnew()
  46. {
  47.      Blockobj *temp;
  48.  
  49.      temp = (Blockobj *) malloc(sizeof(Blockobj));
  50.      
  51.      temp->btype = BLOCK_UNKNOWN;
  52.      temp->Blockname = STRnew();
  53.      temp->datatype  = BDATA_NONE;
  54.      
  55.      return(temp);
  56. }
  57.      
  58.  
  59. /*
  60.  * Initialize the block structure
  61.  */
  62.  
  63. void
  64. BLinit(bl)
  65.   Blockobj *bl;
  66. {
  67.      STRinit(bl->Blockname);
  68.      switch (BLgetDatatype(bl)) {
  69.      case BDATA_FILE:
  70.       STRinit(bl->data.filename);
  71.       break;
  72.      case BDATA_GREF:
  73.       GSinit(bl->data.gs);
  74.       break;
  75.      case BDATA_TEXT:
  76.       STAinit(bl->data.text);
  77.       break;
  78.      }
  79. }
  80.  
  81. /*
  82.  * Calls the right destory fcn depending on the object in the union.
  83.  * 
  84.  * wouldn't c++ be nice right here? :-)
  85.  */
  86.  
  87. static void
  88. BLdatadestroy(bl)
  89.   Blockobj *bl;
  90. {
  91.      switch (BLgetDatatype(bl)) {
  92.      case BDATA_FILE:
  93.       STRdestroy(bl->data.filename);
  94.       break;
  95.      case BDATA_TEXT:
  96.       STAdestroy(bl->data.text);
  97.       break;
  98.      case BDATA_GREF:
  99.       GSdestroy(bl->data.gs);
  100.       break;
  101.      }
  102. }
  103.  
  104. /*
  105.  * Free memory of BlockObj
  106.  */
  107.  
  108. void
  109. BLdestroy(bl)
  110.   Blockobj *bl;
  111. {
  112.      STRdestroy(bl->Blockname);
  113.      BLdatadestroy(bl);
  114.      free(bl);
  115. }
  116.  
  117.  
  118. void
  119. BLcpy(dest, orig)
  120.   Blockobj *dest,*orig;
  121. {
  122.      BLsetName(dest,BLgetName(orig));
  123.      dest->btype = orig->btype;
  124.  
  125.      switch (BLgetDatatype(orig)) {
  126.      case BDATA_FILE:
  127.       BLsetFile(dest, STRget(orig->data.filename));
  128.       break;
  129.      case BDATA_GREF:
  130.       BLsetGref(dest, orig->data.gs);
  131.       break;
  132.      case BDATA_TEXT:
  133.       BLsetText(dest, orig->data.text);
  134.       break;
  135.      }
  136. }
  137.  
  138.  
  139. /*
  140.  * BLgetNumLines() returns the number of lines for the Text record 
  141.  * It returns -1 if this isn't the type of record.
  142.  */
  143.  
  144. int
  145. BLgetNumLines(bl)
  146.   Blockobj *bl;
  147. {
  148.      switch (BLgetDatatype(bl)) {
  149.      case BDATA_TEXT:
  150.       return(STAgetTop(bl->data.text));
  151.      default:
  152.       return(-1);
  153.      }
  154.      ;
  155. }
  156.  
  157.  
  158. /*
  159.  * BLgetLine() returns a character pointer to the line for the Text data type
  160.  */
  161.  
  162. char*
  163. BLgetLine(bl, lineno)
  164.   Blockobj *bl;
  165.   int lineno;
  166. {
  167.      switch (BLgetDatatype(bl)) {
  168.      case BDATA_TEXT:
  169.       return(STRget(STAgetEntry(bl->data.text, lineno)));
  170.      }
  171. }
  172.  
  173.  
  174. /*
  175.  * BLsetFile() sets up a block to contain a file reference.
  176.  * Really handy for the server.
  177.  */
  178.  
  179. void
  180. BLsetFile(bl, filename)
  181.   Blockobj *bl;
  182.   char *filename;
  183. {
  184.      /** Reset data field and put in new values **/
  185.  
  186.      BLdatadestroy(bl);
  187.  
  188.      bl->datatype      = BDATA_FILE;
  189.      bl->data.filename = STRnew();
  190.  
  191.      STRset(bl->data.filename, filename);
  192. }
  193.  
  194.  
  195. /*
  196.  * BLsetText sets everything up for storing text, if the optional parameter
  197.  * sta is set, it copies it in.
  198.  */
  199.  
  200. void
  201. BLsetText(bl, sta)
  202.   Blockobj *bl;
  203.   StrArray *sta;
  204. {
  205.      /** Reset data field and put in new values **/
  206.      if (BLgetDatatype(bl) != BDATA_TEXT) {
  207.       BLdatadestroy(bl);
  208.  
  209.       bl->datatype = BDATA_TEXT;
  210.       bl->data.text = STAnew(10);
  211.      }
  212.      if (sta != NULL) {
  213.       STAcpy(bl->data.text, sta);
  214.      }
  215. }
  216.  
  217.  
  218. /*
  219.  * Keep data in memory, text is a line to be added to the text
  220.  */
  221.  
  222. void
  223. BLaddText(bl, text)
  224.   Blockobj *bl;
  225.   char *text;
  226. {
  227.      String   *tempstr;
  228.      int i;
  229.  
  230.      BLsetText(bl, NULL);
  231.  
  232.      tempstr = STRnew();
  233.      
  234.      STRset(tempstr, text);
  235.      STApush(bl->data.text, tempstr);
  236.  
  237.      STRdestroy(tempstr);
  238. }
  239.  
  240. /*
  241.  * Make the block a gopher-reference
  242.  */
  243.  
  244. void
  245. BLsetGref(bl, gs)
  246.   Blockobj *bl;
  247.   GopherObj *gs;
  248. {
  249.      /** Reset data field and put in new values **/
  250.      BLdatadestroy(bl);
  251.  
  252.      bl->datatype = BDATA_GREF;
  253.      
  254.      bl->data.gs = GSnew();
  255.      
  256.      GScpy(bl->data.gs, gs);
  257.      
  258.      GSdestroy(gs);
  259. }
  260.  
  261.  
  262. /*
  263.  * BLtoNet() transmits the block as per gopher+ protocol
  264.  * if the data field is a file, it opens it and sends it out
  265.  */
  266.  
  267. void
  268. BLtoNet(bl, fd)
  269.   Blockobj *bl;
  270.   int fd;
  271. {
  272.      FILE *infile;
  273.      int i;
  274.      char outputline[512];
  275.  
  276.      /** Switch on data type **/
  277.  
  278.      sprintf(outputline, "+%s:", BLgetName(bl));
  279.      writestring(fd, outputline);
  280.  
  281.      switch (BLgetDatatype(bl)) {
  282.  
  283.      case BDATA_GREF:
  284.       writestring(fd, " ");
  285.       GStoNet(bl->data.gs,fd);
  286.       break;
  287.  
  288.      case BDATA_TEXT:
  289.       writestring(fd, "\r\n");
  290.       for (i=0; i<STAgetTop(bl->data.text); i++) {
  291.            writestring(fd, " ");
  292.            writestring(fd, STAgetEntry(bl->data.text, i));
  293.            writestring(fd, "\r\n");
  294.       }
  295.       break;
  296.  
  297.      case BDATA_FILE:
  298.       writestring(fd, "\r\n");
  299.  
  300.       if ((infile = fopen(STRget(bl->data.filename), "r"))==NULL)
  301.            break;
  302.       
  303.       while (fgets(outputline, sizeof(outputline), infile)!=NULL)  {
  304.            ZapCRLF(outputline);
  305.            writestring(fd, " ");
  306.            writestring(fd, outputline);
  307.            writestring(fd, "\r\n");
  308.       }
  309.       fclose(infile);
  310.       break;
  311.      }
  312. }
  313.  
  314.  
  315. /*
  316.  * BLfromNet() assumes that the initial '+' in the data stream has been read,
  317.  * along with the blockname, up to the ':', but not anything after..
  318.  * 
  319.  * It then executes most of the state diagram, it returns when it has
  320.  * encountered EOF, or encounters the next '+', or '.'
  321.  *
  322.  * Returns the following:
  323.  *  0 for EOF encountered, block retrieved successfully
  324.  *  1 for successful retrieve, and another block coming
  325.  *  neg value for error conditions from read routines and botched block vals
  326.  */
  327.       
  328. int
  329. BLfromNet(bl, fd, blockname)
  330.   Blockobj *bl;
  331.   int fd;
  332.   char *blockname;
  333. {
  334.      char inputline[512];
  335.      int err;
  336.      char *cp;
  337.  
  338.  
  339.      /*** State: _GotBlockName_ ***/
  340.  
  341.      BLsetName(bl, blockname);
  342.  
  343.      /** Find out if there's a gopher reference **/
  344.      err = readrecvbuf(fd, inputline, 1);
  345.      
  346.      if (*inputline == ' ') {
  347.       /** GREF coming up, State: _GotBnameSpace_ **/
  348.       GopherObj *gs;
  349.  
  350.       gs = GSnew();
  351.       GSfromNet(gs, fd);
  352.       BLsetGref(bl, gs);
  353.       /** read up to the next \r\n+ **/
  354.       while (1) {
  355.            if ((err= readrecvbuf(fd, inputline, 1)) <= 0)
  356.             return(err);
  357.            if (*inputline == '+')
  358.             return(1);
  359.            else {
  360.             err = readline(fd, inputline, sizeof(inputline));
  361.             if (err <= 0)
  362.              return(err); /*** Error ***/
  363.            }
  364.       }
  365.      }
  366.      
  367.      /** Okay, let's just stick the text in verbatim **/
  368.  
  369.      /** get rid of remaining newline **/
  370.      readline(fd, inputline, sizeof(inputline));
  371.  
  372.      /** State: _FirstChar_ **/
  373.  
  374.      while (1) {
  375.       /** Check for plus **/
  376.       if ((err= readrecvbuf(fd, inputline, 1)) <=0)
  377.            return(err);
  378.       
  379.       if (*inputline == '+')
  380.            return(1);
  381.            /*** Return to state _NewBlock_ ***/
  382.       
  383.       if (*inputline == '.') {
  384.            readline(fd, inputline, sizeof(inputline));
  385.            return(0);
  386.       }
  387.  
  388.       /** add a line otherwise   State: _Addline_ **/
  389.       readline(fd, inputline, sizeof(inputline));
  390.       ZapCRLF(inputline);
  391.       BLaddText(bl, inputline);
  392.      }
  393. }
  394.  
  395.  
  396. int
  397. BLAsearch(bla, bname)
  398.   BlockArray *bla;
  399.   char *bname;
  400. {
  401.      int i;
  402.      
  403.      for (i=0; i<BLAgetTop(bla); i++) {
  404.       if (strcmp(BLgetName(BLAgetEntry(bla,i)), bname)==0)
  405.            return(i);
  406.      }
  407.      
  408.      return(-1);
  409. }
  410.  
  411.